<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<title>User Settings: FAQ</title>
<link rel="stylesheet" href="http://dev.eclipse.org/default_style.css" type="text/css">
</head>
<body text="#000000" bgcolor="#FFFFFF">


<table BORDER=0 CELLSPACING=5 CELLPADDING=2 WIDTH="100%" >
  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica" color="#FFFFFF">User Settings: FAQ</font></b></td>
  </tr>

  <tr>
    <td align="left" colspan="2"> 
		<font size=-1><i>last updated: January 19, 2005</i></font>
	</td>
  </tr>

  <tr>
    <td align="left" colspan="2"> 
	General:
	<ol>
        <li><a href="#whatIs">What is a scope?</a></li>
        <li><a href="#platformScopes">What scopes are contributed by the Platform?</a></li>
        <li><a href="#tree">This is confusing, how can I picture this in my mind?</a></li>
        <li><a href="#basicGet">How do I know if auto-build is turned on? (How do I get a preference value?)</a></li>
        <li><a href="#basicSet">How can I set the auto-build preference? (How do I set a preference value?)</a></li>
        <li><a href="#backwardsCompatibilityScopes">Why doesn't the backwards compatibility layer check all the scopes for a value?</a></li>
		<li><a href="#flush">When are my preference changes saved to disk?</a></li>
		<li><a href="#customization">How does the plug-in customization story work?</a></li>
      </ol>
	Conversion:
	<ol>
        <li><a href="#convert">What should I do to convert my code to the new mechanism?</a></li>
        <li><a href="#convertProject">How do I convert my project property page to use project preferences?</a></li>
		<li><a href="#imemento">How do I convert my IMemento values?</a></li>
	</ol>
	Listeners:
	<ol>
		<li>How do I know when changes have happened to my preference?</li>
		<li>But I want to listen to changes in ALL scopes, not just one.</li>
	</ol>
	Nodes:
	<ol>
		<li><a href="#nodes">Why should I use nodes?</a></li>
		<li><a href="#illegalStateException">Why am I getting an IllegalStateException when calling APIs?</a></li>
	</ol>
	Extensions:
	<ol>
        <li><a href="#extension">How do I extend the preferences and add my own scope?</a></li>
	</ol>
    </td>
  </tr>
	

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="whatIs"></a>What is a 
      scope?</b><p></p>
	In Eclipse 2.1 there was only one place to store preferences via the Runtime APIs. 
	Users would ask a particular plug-in for its preferences 
	(<code>Plugin.getPluginPreferences()</code>) and the preferences would be store per plug-in, 
	per workspace. This allowed some conveniences but it was obvious that 
	the new preference mechanism needed to be extensible and allow settings to be 
	stored in different places...users want to share their preferences between 
	workspaces, configurations, and even share them with other users. This is the 
	main reason that we created "scopes" for the preference store.
	<p>
	A scope basically refers to where the preferences are stored. Different 
	preference scopes can be contributed by plug-ins so the number of scopes 
	available to clients is not limited to those defined by the platform.
	</p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="platformScopes"></a>What 
      scopes are contributed by the Platform?</b><p></p>
	INSTANCE - 
	The instance scope can also be thought of as "workspace". That is, the 
	preferences which are stored in this scope are stored per workspace, or 
	per running instance of Eclipse. This scope corresponds to the default 
	location of preferences in Eclipse 2.1. The instance area is derived from 
	the location returned by <code>org.eclipse.core.runtime.Platform#getInstanceLocation()</code>. 
	Preferences stored in this scope will not be available to other running instances 
	of Eclipse.
	<p></p>
	CONFIGURATION - The configuration scope is used to store preferences on a per 
	configuration level. Being able store preferences per configuration means 
	that all workspaces share the same preferences. For instance, if you are an 
	Eclipse developer and you have a single Eclipse install but you have multiple 
	workspaces for different projects/branches that you are working on, the 
	preferences stored in the configuration scope will be shared between these 
	workspaces. The configuration area is derived from the location returned by 
	<code>org.eclipse.core.runtime.Platform#getConfigurationLocation()</code>.	
	<p></p>
	DEFAULT - The default preference scope was initially created to provide a backwards 
	compatibility story for the plug-in customization code in Eclipse 2.1. Preferences 
	stored in the default scope are not persisted to disk and are a part of the plug-in
	customization story.
	<p></p>
	PROJECT - There was a request for per project preferences so the project scope 
	handles this. Preferences which are stored in this scope are shared stored in the 
	project content area and are therefore automatically shared with the repository. 
	This enables items like java compiler settings to be shared between team members 
	working on the same project. 
    </td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="tree"></a>This 
      is confusing, how can I picture this in my mind?</b>
	  <p></p>
	The preferences can be thought of as a tree with each node 
      having a name and children. The "path" of a node is the names of it and 
      all its ancestors separated by a path separator. 
      <p>
	Start at the root node. The root node's name 
	is empty and has a path of "/". The root node's children are the names of the scopes
	which are defined. (e.g. instance, configuration, user, default, project, etc) Therefore
	their paths are: /instance, /configuration, /user, /default, and /project.
	</p><p>
	 The path structure under the scope name is defined by the scope itself. The scopes
	 contributed by the Platform Runtime (instance, configuration, user, default) define
	 the next segement to be a qualifier. (like a plug-in or bundle id)
	An example of the full path for the autobuild preference for the resources plug-in 
	in the instance scope would be:<br>
	&nbsp;&nbsp;&nbsp;&nbsp;<code>/instance/org.eclipse.core.resources/description.autobuild</code>
	</p><p>
	The project scope (as defined by the resources plug-in) defines its path structure to be
	<code>/project/&lt;projectName&gt;/&lt;qualifier&gt;/key</code> and therefore the full path for
	the resources' plug-in auto-build preference for the project "MyProject" would be:<br>
	&nbsp;&nbsp;&nbsp;&nbsp;<code>/project/MyProject/org.eclipse.core.resources/description.autobuild</code>
	</p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="basicGet"></a>How do I know if 
      auto-build is turned on? (How do I get a preference value?)</b>
	  <p></p>
	  </td>
  </tr>
  
  <tr>
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">1.</td>
    <td WIDTH="98%">
Through the backwards compatibility layer.
<p>All the plug-in preference APIs which existed in Eclipse 2.1 still exist and 
  are fully supported through a backwards compatibility layer. All the client has
  to do is ask the org.eclipse.core.resources plug-in for its preferences.</p>
  <p>The downside to this is that not all of the preference scopes are checked
  for a value. In this case first the INSTANCE scope is checked, and then the
  DEFAULT scope. If a value doesn't exist in either scope, then the default-default
  value for that type is returned.</p>
      <p> <code>
	  String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
      return ResourcesPlugin.getPluginPreferences().getBoolean(key);<br>
	  </code> </p>
    </td>
  </tr>
  
  <tr>
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">2.</td>
    <td WIDTH="98%"> 
Via navigation from the root node.
<p>The new Eclipse preference mechanism is structured in a hierarchial means and 
  therefore the user is able to retrieve the root of the hierarchy and navigate 
  to the particular preference node that they desire. This is, of course, assuming 
  the know the path structure of the node they are trying to retrieve. The example
  below retrives the value from the INSTANCE scope.</p>
<p> <code>
    String qualifier = ResourcesPlugin.getDescriptor().getUniqueIdentifier();<br>
	String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
	boolean defaultValue = false;<br>
    Preferences node = Platform.getPreferencesService().getRootNode().node(InstanceScope.SCOPE).node(qualifier);<br>
    return node.getBoolean(key, defaultValue);</code> </p>
  </td>
  </tr>

  <tr>
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">3.</td>
    <td WIDTH="98%"> 
Through the context objects.
<p>If the user knows which preference scope their preference is in but they don't know
the hierarchy structure of the scope (or don't want to have to deal with it), then they
are able to use the scope context API to retrieve the correct node for their preferences.</p>
<p> <code>
    String qualifier = ResourcesPlugin.getDescriptor().getUniqueIdentifier();<br>
	String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
	boolean defaultValue = false;<br>
    Preferences node = new InstanceScope().getNode(qualifier);<br>
	if (node != null)<br>
    &nbsp;&nbsp;return node.getBoolean(key, defaultValue);</code> </p>
  </td>
  </tr>
  
  <tr>
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">4a.</td>
    <td WIDTH="98%"> 
Search through the preferences service. (manual lookup order)
<p>Having preferences stored in a single location, although useful, is uninteresting 
  compared to being able to store preferences in multiple scopes. If a user has 
  a collection of multiple preference nodes that they would like to check for 
  a particular preference value, then they are able to use the API on IPreferencesService 
  to check the multiple nodes and return the first found value, or the specified 
  default if it is not found. The example below first checks the INSTANCE scope and
  then checks the USER scope.</p>
<p> <code>
  IPreferencesService service = Platform.getPreferencesService();<br>
  String qualifier = ResourcesPlugin.getDescriptor().getUniqueIdentifier();<br>
  String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
  String defaultValue = "false";<br>
  Preferences root = service.getRootNode();<br>
  Preferences instanceNode = root.node(InstanceScope.SCOPE).node(qualifier);<br>
  Preferences userNode = root.node(UserScope.SCOPE).node(qualifier);<br>
  Preferences[] nodes = new Preferences[] {instanceNode, userNode};<br>
  return service.get(key, defaultValue, nodes);<br>
  </code> </p>
  </td>
  </tr>

  <tr>
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">4b.</td>
    <td WIDTH="98%"> 
Search through the preferences service. (default lookup order)
<p>Navigation from the root node to other nodes in the preference hierarchy can 
  be cumbersome so we expect most preference users to take advantage of this second 
  API. It is a convenience method to the above method.</p>
<p>First they (in most cases the plug-in developer who is contributing the preference) 
set the scope lookup order (if none is specified then the default-default 
  {project, instance, configuration, user, default} is used. </p>
      <p>Some scopes require extra context to determine which preference nodes 
        are the right ones to look at. So if necessary, callers are able to create 
        IScopeContext instances to aid in lookup. <em>Note that these are not 
        necessary for the INSTANCE, CONFIGURATION, USER, and DEFAULT scopes.</em> 
      </p>
      <p>
In the example below, we first look to see if the preference has been set on the project
preferences for "MyProject" and then we check the INSTANCE preferences.
</p><p>
 <code>
  IPreferencesService service = Platform.getPreferencesService();<br>
  String qualifier = ResourcesPlugin.getDescriptor().getUniqueIdentifier();<br>
  String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
  boolean defaultValue = false;<br>
  String[] lookupOrder = new String[] {ProjectScope.SCOPE, InstanceScope.SCOPE};<br>
  service.setDefaultLookupOrder(qualifier, key, lookupOrder);<br>
  IScopeContext contexts = new IScopeContext[] {new ProjectScope("MyProject")};<br>
  return service.getBoolean(qualifier, key, defaultValue, contexts);</code> </p>
  </td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="basicSet"></a>How can I set the 
      auto-build preference? (How do I set a preference value?)</b></td>
  </tr>

  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">1.</td>
    <td WIDTH="98%"> 
Through the backwards compatibility layer.
<p>Again, all the old APIs exist and are fully functional.</p>
<p> <code>
	  String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
	  boolean value = true;<br>
	  ResourcesPlugin.getPluginPreferences().setValue(key, value);<br>
  </code> </p>
    </td>
  </tr>
  
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">2.</td>
    <td WIDTH="98%"> 
Via navigation from the root node.
<p>If the user knows which scope they wish to store the preference in and  
  knows the path structure for the hierarchy of that scope, then they are able 
  to navigate directly to that preference node and set their preference value. In
  the example below we are setting the auto-build setting in the INSTANCE scope.</p>
<p> <code>
	  String qualifier = ResourcesPlugin.getDescriptor().getUniqueIdentifier();<br>
	  String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
        boolean value = true;<br>
	  IEclipsePreferences root = Platform.getPreferencesService().getRootNode();<br>
	  root.node(InstanceScope.SCOPE).node(qualifier).putBoolean(key, value);<br>
  </code> </p>
    </td>
  </tr>

  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%">3.</td>
    <td WIDTH="98%"> 
Through the scope context.
      <p>If the user knows which scope they wish to set the preference value in 
        but doesn't know the path structure for that scope, (or prefers not to 
        navigate it themselves) then they can use the convenience methods in IScopeContext 
        to determine the correct preference node. This is the method in which 
        we envision most clients setting preference values. In the example below 
        we are storing the preference in the project preferences for "MyProject".</p>
<p> <code>
	String qualifier = ResourcesPlugin.getDescriptor().getUniqueIdentifier();<br>
	String key = ResourcesPlugin.PREF_AUTO_BUILDING;<br>
        boolean value = true;<br>
	IScopeContext context = new ProjectScope(MyProject);<br>
	IEclipsePreferences node = context.getNode(qualifier);<br>
	if (node != null)<br>
	&nbsp;&nbsp;&nbsp;&nbsp;node.putBoolean(key, value);</code> </p>
    </td>
  </tr>
  
  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="convert"></a>What 
      should I do to convert my code to the new mechanism?</b>
	  <p></p>
	Getting a value using the old code only checks the INSTANCE and DEFAULT scopes:<br>
		<code>
		&nbsp;&nbsp;ResourcesPlugin.getPluginPreferences().getBoolean(key);</br>
		</code>
	</p><p>
	Getting a value using the new code looks in all scopes as defined by the look-up order
	set in the preferences service:<br>
		<code>
		&nbsp;&nbsp;Platform.getPreferencesService().getBoolean(ResourcesPlugin.PI_RESOURCES, key, defaultValue);<br>
		</code>
	</p><p>
	Setting a value using the old code either puts the value in the INSTANCE scope or clears
	it if it is the same as the value in the DEFAULT scope:<br>
		<code>
		&nbsp;&nbsp;ResourcesPlugin.getPluginPreferences().setValue(key, value);<br>
		</code>
	</p><p>
	Setting a value using the new code is a bit more complicated. Clients must know which
	scope they wish to store their value in. For instance:<br>
		<code>
		&nbsp;&nbsp;Preferences node = new InstanceScope().getNode(ResourcesPlugin.PI_RESOURCES);<br>
		&nbsp;&nbsp;if (node != null)<br>
		&nbsp;&nbsp;&nbsp;&nbsp;node.put(key, value);<br>
		</code>
	</p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="convertProject"></a>How 
      do I convert my project property page to use project preferences?</b>
	  <p></p>
	Rather than use the generalized look-up mechanism to find out your project-specific
	values, I would create a project context and do the lookup from there. This ensures
	that you either get the value that is defined in the project scope or nothing. (the
	default value that you specify) For example:
	<p>
		<code>
		// setup<br>
		IScopeContext context = new ProjectScope(MyProject);<br>
        IEclipsePreferences node = context.getNode("org.eclipse.jdt.core");<br>
		int defaultValue = JavaCore.SEVERITY_IGNORE;<br>
		String key = JavaCore.NON_NLS_SEVERITY;<br>
		int value = defaultValue;<br>
		</code><p></p>
		<code>...</code><p></p>
		<code>
		// get the value<br>
		if (node != null) <br>
		&nbsp;&nbsp;value = node.getInt(key, defaultValue);<br>
		if (value == defaultValue) {<br>
		&nbsp;&nbsp;// value isn't set in the project scope.<br>
		&nbsp;&nbsp;// value is "inherited" from another scope.<br>
		} else {<br>
		&nbsp;&nbsp;// we have a value set in the project scope<br>
		}<br>
		<p></p>
		</code>
		<code>...</code><p></p>
		<code>
		// set the value<br>
		if (node != null) {<br>
		&nbsp;&nbsp;if (value == defaultValue) {<br>
		&nbsp;&nbsp;&nbsp;&nbsp;// value is same as default so no need to store it<br>
		&nbsp;&nbsp;&nbsp;&nbsp;node.remove(key);<br>
		&nbsp;&nbsp;} else {<br>
		&nbsp;&nbsp;&nbsp;&nbsp;// set a project-specific value<br>
		&nbsp;&nbsp;&nbsp;&nbsp;node.put(key, value);<br>
		}<br>
		</code>
		<p></p>
		<code>...</code><p></p>
		<code>
		// save the changes<br>
		if (node != null) {<br>
		&nbsp;&nbsp;// save the project specific values<br>
		&nbsp;&nbsp;node.flush();<br>
		}<br>
		</code>
	</p>
	</td>
  </tr>
  
  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="imemento"></a>How do I convert my IMemento values?</b>
	<p></p>
	Its easy! IMementos are a method of storing hierarchial data and that's just what the node
	hierarchy is. 
	<p>To set a complex IMemento preference value using Eclipse 2.1 preferences:
	</p><p>
		<code>
		String key = "providers";<br>
		XMLMemento root = XMLMemento.createWriteRoot(key);<br>
		IMemento dev = root.createChild("dev.eclipse.org");<br>
		dev.putString("connnectionType", "pserver");<br>
		dev.putString("login", "anonymous");<br>
		dev.putString("path", "/cvsroot/eclipse");<br>
		IMemento example = root.createChild("cvs.example.com");<br>
		example.putString("connnectionType", "pserver");<br>
		example.putString("login", "anonymous");<br>
		example.putString("path", "/home/cvs");<br>
		Writer writer = new StringWriter();<br>
		try {<br>
		&nbsp;&nbsp;root.save(writer);<br>
		} finally {<br>
		&nbsp;&nbsp;writer.close();<br>
		}<br>
		MyPlugin.getDefault().getPluginPreferences().setValue(key, writer.toString());<br>
		...<br>
		MyPlugin.getDefault().savePluginPreferences();<br>
		</code>
	</p><p>
	To set the same complex values using Eclipse 3.0 preferences:
	</p><p>
		<code>
		// Note: can create other context here including Project<br>
		IScopeContext context = new InstanceScope();<br>
		Preferences root = context.getNode("org.eclipse.team");<br>
		// Note: should not be null<br>
		if (root != null) {<br>
		&nbsp;&nbsp;Preferences dev = root.node("providers/dev.eclipse.org");<br>
		&nbsp;&nbsp;dev.put("connectionType", "pserver");<br>
		&nbsp;&nbsp;dev.put("login", "anonymous");<br>
		&nbsp;&nbsp;dev.put("path", "/cvsroot/eclipse");<br>
		&nbsp;&nbsp;Preferences example = root.node("providers/cvs.example.com");<br>
		&nbsp;&nbsp;example.put("connectionType", "pserver");<br>
		&nbsp;&nbsp;example.put("login", "anonymous");<br>
		&nbsp;&nbsp;example.put("path", "/home/cvs");<br>
		&nbsp;&nbsp;...<br>
		&nbsp;&nbsp;root.flush();<br>
		}<br>
		</code>
	</p><p>
	To get a value using the Eclipse 2.1 preferences:
	</p><p>
		<code>
		String xmlString = MyPlugin.getDefault().getPluginPreferences().getString("providers");<br>
		Reader reader = new StringReader(xmlString);<br>
		XMLMemento root = XMLMemento.createReadRoot(reader);<br>
		IMemento dev = root.getChild("dev.eclipse.org");<br>
		return dev.getString("connnectionType");<br>
		</code>
	</p><p>
	To get the same value using Eclipse 3.0 preferences:
	</p><p>
		<code>
		// Note: can create other context here including Project<br>
		IScopeContext context = new InstanceScope();<br>
		Preferences root = context.getNode("org.eclipse.team");<br>
		// Note: should not be null<br>
		if (root != null) {<br>
		&nbsp;&nbsp;Preferences node = root.node("providers/dev.eclipse.org");<br>
		&nbsp;&nbsp;return node.get("connectionType", null);<br>
		}<br>
		</code>
	</p>
	</td>
  </tr>


  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="backwardsCompatibilityScopes"></a>Why 
      doesn't the backwards compatibility layer check all the scopes for a value?</b>
	  <p></p>
	The backwards compatibility layer only checks for preference values in the INSTANCE and
	DEFAULT scopes for two main reasons.
	<p>
	Firstly. we wanted to maintain true backwards compatibility. If the "get" methods checked
	for preference values in scopes other than INSTANCE and DEFAULT, then the behaviour would
	not be the same as was in Eclipse 2.1. That is, if there was a value set for another
	scope it would be returned.
	</p><p>
	The second reason is that it confuses the current UI story. People have created many
	preference pages which show the current preference values. This maps on to the preferences
	stored in the INSTANCE scope. If we changed the backwards compatibility story to look
	in the other scopes for preference values, then the values presented to the user would
	be mixed...some would be from the INSTANCE scope, some from the USER scope, etc etc.
	</p><p>
	The short story is that we have to try to develop a UI which presents preferences and 
	their scopes to the user in a simple and managable way.
	</p>
	</td>
  </tr>
  
  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="flush"></a>When are my preference changes saved to disk?</b>
	<p></p>
	The short answer is "whenever you change them you need to save them". In Eclipse 2.1 there 
	was API to save plug-in preferences (<code>Plugin.savePluginPreferences()</code>) which clients
	were encouraged to call on plug-in shutdown and when they changed their preference values
	(like in a preference page).
	<p>
	It is important to note that this old API now corresponds to saving the preferences for 
	that plug-in in the INSTANCE scope only. 
	</p><p>
	Now, it is recommended that people save their preference changes to disk by calling the
	<code>Preferences.flush()</code> method. For instance, preference page owners would 
	call this after setting all the preference values when the user hits "OK".
	</p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="nodes"></a>Why should I use nodes?</b>
	<p></p>
	For most plug-ins, simple key/value pairs are well suited for their preference 
	values and they will never have to take advantage of the node hierarchy other than
	the basic traversal. The interesting use case is for those clients who previously used 
	mark-up (like XML)
	to encode their preference values. XML and its elements are essentially containers...a
	way to group together similar values in a hierarchical manner. The use of nodes can
	simplify this for clients.
	</p><p>
	Each node in the hierarchy has a name and its path is represented by its name and
	all its parents' names separated by the path separator. This allows preference keys
	at arbitrary depths in the tree so a node's children nodes could be used in a "contains"
	relationship.
	</p><p>
	Think, for instance, of the list of Team provider connections in Eclipse. Rather than
	having a single preference key and the value being wrapped in a wad of XML, it could
	be split across multiple nodes and be more accessible. For instance consider the
	following:
	<p>
	<code>&nbsp;&nbsp;/instance/org.eclipse.team/providers/example.com/path=/cvsroot/eclipse</code><br>
	<code>&nbsp;&nbsp;/instance/org.eclipse.team/providers/example.com/login=anonymous</code><br>
	<code>&nbsp;&nbsp;/instance/org.eclipse.team/providers/example.com/connectionType=pserver</code><br>
	<code>&nbsp;&nbsp;/instance/org.eclipse.team/providers/dev.eclipse.org/path=/cvsroot/eclipse</code><br>
	<code>&nbsp;&nbsp;/instance/org.eclipse.team/providers/dev.eclipse.org/login=anonymous</code><br>
	<code>&nbsp;&nbsp;/instance/org.eclipse.team/providers/dev.eclipse.org/connectionType=pserver</code><br>
	</p>
	In this example the list of providers could be retrieved as children of the 
	<code>/instance/org.eclipse.team/providers</code> node and then each individual provider's
	login information as preferences in children nodes.
	</p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><b><a name="illegalStateException"></a>Why am I getting an IllegalStateException when calling APIs?</b>
	<p></p>
		Since the Preferences APIs include the ability to add nodes to the hierarchy, they
		also include methods to remove nodes from the hierarchy. If a node has been removed and
		a client still has a reference to it, the client will get an
		<code>IllegalStateException</code> when calling APIs on that node. The only valid methods
		to call on a removed node are: <code>name(), absolutePath()</code> and <code>nodeExists()</code>.
		<p>
		If clients aren't sure whether or not their node may have been removed since the last
		time they accessed it, they are encouraged to re-retrieve the node from the hierarchy.
		</p><p>
		<code>
		if (!node.nodeExists(""))<br>
		&nbsp;&nbsp;&nbsp;&nbsp;node = service.getRootNode().node(node.absolutePath());<br>
		</code>
		</p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><p><b><a name="customization"></a>How does the plug-in customization 
        story work?</b> </p>
      <p>Check out the separate <a href="plugin_customization.html">document</a> 
        on plug-in customization. It explains the order that preference defaults are applied
		and compares this to the way it worked in Eclipse 2.1.</p>
      <p></p>
	</td>
  </tr>

  <tr> 
    <td ALIGN=LEFT VALIGN=TOP COLSPAN="2"><hr></td>
  </tr>
  <tr> 
    <td ALIGN=RIGHT VALIGN=TOP WIDTH="2%"><img SRC="../../images/Adarrow.gif" BORDER=0 height=16 width=16></td>
    <td WIDTH="98%"><p><b><a name="extension">How do I extend the preferences and add my own scope?</a></b> </p>
		
      <p>1. Extend the org.eclipse.core.runtime.preferences extension point. 
	  <code><pre>
	&lt;extension point=&quot;org.eclipse.core.runtime.preferences&quot;&gt;
	&nbsp;&nbsp;&nbsp;&nbsp;&lt;scope name=&quot;myScope&quot; class=&quot;com.example.preferences.MyScope&quot;/&gt;
	&lt;/extension&gt;
      </pre></code>
	  </p>
	  <p>2. Have your class implement IScope and IEclipsePreferences.
	  <code><pre>
	  public class MyScope implements IScope, IEclipsePreferences {
	  &nbsp;&nbsp;&nbsp;&nbsp;...
	  }
	  </pre></code>
	  </p>
      <p>Here is an <a href="example_scope.zip">example</a> plug-in which creates a new scope.</p>
      <p></p>
	</td>
  </tr>
  
</table>
